#include "dht11_menu.h"
#include "menu_config.h"
#include "./SYSTEM/Task/cot_task.h"
#include "./BSP/DHT11/dht11.h"

/* 显示刷新标志 */
static bool sg_needRefresh = true;
/* 全屏刷新标志 */
static bool needFullRefresh = true;

/* DHT11传感器状态枚举 */
typedef enum {
    DHT11_STATE_INIT,       /* 初始化状态 */
    DHT11_STATE_WAIT,       /* 等待稳定状态 */
    DHT11_STATE_READY       /* 准备读取状态 */
} DHT11_State_t;

/* 定义空的菜单项 */
static cotMenuList_t sg_DHT11MenuTable[] =
{
    COT_MENU_ITEM_BIND(TEXT_DHT11_TEMP_HUMI, NULL, NULL, NULL, NULL, "DHT11 Temperature & Humidity"),
};

/**
 * @brief       DHT11温湿度显示任务
 * @details     读取DHT11温湿度并通过串口和LCD显示，同时检测传感器连接状态
 * @param       无
 * @retval      无
 */
void DHT11_TempHumiDisplayTask(void)
{
    uint8_t temperature, humidity;
    static char str_buf[20];
    
    /* 静态变量保存状态，确保在多次函数调用间保持状态 */
    static DHT11_State_t dht11_state = DHT11_STATE_INIT;
    
    /* 根据DHT11状态进行不同处理 */
    switch (dht11_state)
    {
        case DHT11_STATE_INIT:
            /* 初始化状态 */
            if (dht11_init() == 0)  /* 初始化DHT11并检查状态 */
            {
                /* 初始化成功，进入等待状态 */
                dht11_state = DHT11_STATE_WAIT;
                printf("DHT11 init OK\r\n");
                LCD_ShowString(10, 80, (uint8_t *)"Init OK...     ", g_point_color, g_back_color, 32, 0);
                LCD_ShowString(10, 120, (uint8_t *)"              ", g_back_color, g_back_color, 32, 0);
            }
            else
            {
                /* 初始化失败，显示错误信息并保持在初始化状态，下次任务执行时会再次尝试初始化 */
                printf("DHT11 init failed!\r\n");
                LCD_ShowString(10, 80, (uint8_t *)"Sensor Error!   ", RED, g_back_color, 32, 0);
                LCD_ShowString(10, 120, (uint8_t *)"Checking...    ", RED, g_back_color, 32, 0);
            }
            break;
            
        case DHT11_STATE_WAIT:
            /* 等待状态，显示等待信息并直接返回，利用任务周期实现延时 */
            LCD_ShowString(10, 80, (uint8_t *)"Waiting...", g_point_color, g_back_color, 32, 0);
            
            /* 切换到准备读取状态，下一次任务执行时将读取数据 */
            dht11_state = DHT11_STATE_READY;
            printf("DHT11 ready to read\r\n");
            return;  /* 直接返回，等待下一次任务执行 */
            
        case DHT11_STATE_READY:
            /* 准备读取状态，可以读取数据 */
            /* 获取温湿度值 */
            if (dht11_read_data(&temperature, &humidity) == 0)  /* 读取成功 */
            {
                /* 打印温湿度值到串口 */
                printf("Temperature: %d C, Humidity: %d %%\r\n", temperature, humidity);
                
                /* 在LCD上显示温度值 */
                sprintf(str_buf, "Temp: %d C      ", temperature);
                LCD_ShowString(10, 80, (uint8_t *)str_buf, g_point_color, g_back_color, 32, 0);
                
                /* 在LCD上显示湿度值 */
                sprintf(str_buf, "Humi: %d %%      ", humidity);
                LCD_ShowString(10, 120, (uint8_t *)str_buf, g_point_color, g_back_color, 32, 0);
            }
            else  /* 读取失败 */
            {
                printf("DHT11 Read Error!\r\n");
                dht11_state = DHT11_STATE_INIT;  /* 返回初始化状态，尝试重新初始化 */
                
                /* 在LCD上显示错误信息 */
                LCD_ShowString(10, 80, (uint8_t *)"Read Error!    ", RED, g_back_color, 32, 0);
                LCD_ShowString(10, 120, (uint8_t *)"               ", g_back_color, g_back_color, 32, 0);
            }
            break;
            
        default:
            dht11_state = DHT11_STATE_INIT;  /* 异常状态，重新初始化 */
            break;
    }
}

/* 按键回调函数 - 返回键(KEY2) */
static void OnKey2FunCB(cotKey_t key)
{
    /* 处理按键短按和长按 */
    if (!cotKey_IsLongPress(key))
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 按下首次触发 */
        {
            /* 预留：首次按下按键时的处理 */
        }
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 识别到短按 */
        {
            /* 返回上级菜单 */
            cotMenu_Exit(false);
        }
    }
    else
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 识别到长按 */
        {
            while (cotMenu_Exit(true) == 0)
            {
            }
        }
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 长按松开 */
        {
            /* 预留：长按确认键松手时的处理 */
        }
    }
}

/* 显示回调函数 */
static void ShowDHT11Menu(cotMenuShow_t *ptShowInfo)
{
    /* 如果不需要刷新显示，直接返回 */
    if (!sg_needRefresh)
    {
        return;
    }
    
    /* 只有在首次显示或标记需要全刷时才清屏并绘制所有内容 */
    if (needFullRefresh)
    {
        /* 清屏 */
        LCD_Clear();
        
        /* 显示标题 */
        const char *pszTitle = get_text(TEXT_DHT11_TEMP_HUMI);
        uint16_t titleX = CALC_TITLE_CENTER_X(pszTitle, LCD_W);
        LCD_ShowString(titleX, 0, (uint8_t *)pszTitle, g_point_color, g_back_color, MENU_FONT_SIZE, 0);
        
        /* 在标题下方画一条横线 */
        LCD_DrawLine(0, MENU_FONT_SIZE, LCD_W - 1, MENU_FONT_SIZE, g_point_color);
        
        needFullRefresh = false;
    }
    
    /* 清除刷新标志 */
    sg_needRefresh = false;
}

/* 进入回调函数 */
void OnDHT11MenuEnter(const cotMenuItemInfo_t *ptItemInfo)
{
    /* 绑定菜单表和显示函数 */
    cotMenu_Bind(sg_DHT11MenuTable, COT_GET_MENU_NUM(sg_DHT11MenuTable), ShowDHT11Menu);
    
    /* 创建DHT11温湿度显示任务，周期为1000ms (1秒)，确保符合DHT11采样周期要求 */
    cotTask_Creat(DHT11_TempHumiDisplayTask, 1000, 10);
}

/* 退出回调函数 */
void OnDHT11MenuExit(const cotMenuItemInfo_t *ptItemInfo)
{
    /* 销毁DHT11温湿度显示任务 */
    cotTask_Destory(DHT11_TempHumiDisplayTask);
}

/* 加载回调函数 */
void LoadDHT11Menu(const cotMenuItemInfo_t *ptItemInfo)
{
    /* 注册返回键回调 */
    cotKey_Listen(KEY2, OnKey2FunCB);
    
    /* 配置按键模式 */
    cotKey_ConfigLongPressMode(KEY2, 2000, 0);  /* 设置KEY2键2秒长按，不重复触发 */
    
    /* 标记需要刷新且全屏刷新 */
    sg_needRefresh = true;
    needFullRefresh = true;
} 
